package oop.ex3.search;
import java.util.*;

/**
 * Description: this method implements the DFS search and searches SearchBoardNode objects recursively
 * and returns the best solution in minimum time for organizing the board with a given limited time,
 * and a maximum depth.
 * @author yossavi dawn16889
 */
public class MyDepthFirstSearch <B extends SearchBoardNode<M>, M extends SearchMove> implements DepthFirstSearch<B,M>  {
	private int depth = 0;
	private long initialTime = new Date().getTime();
	private B bestSolution = null;

	/* (non-Javadoc)
	 * @see oop.ex3.search.DepthFirstSearch#search(oop.ex3.search.SearchBoardNode, int, long)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public B search(B startBoard, int maxDepth, long timeOut) {
		
		long newTime = new Date().getTime();
		
		//saves the new best solution
		if (bestSolution==null || startBoard.getQuality()>=bestSolution.getQuality())
			bestSolution=(B) startBoard.getCopy();
		
		//checks if search must end
		boolean isBreak=false;
		if (bestSolution.isBestSolution() || depth==maxDepth || timeOut<=(newTime-initialTime)) {
			isBreak=true;
			return bestSolution;	
		}
		
		Iterator<M> movesIterator = startBoard.getMovesIterator();
		
		//goes over the iterator
		while (movesIterator.hasNext() && !isBreak){
			
			M currentMove = movesIterator.next();
			startBoard.doMove(currentMove);
			depth++;
			if (startBoard.getQualityBound()>=bestSolution.getQuality())
				search(startBoard, maxDepth, timeOut);
			depth--;
			startBoard.undoMove(currentMove);
		}
		return bestSolution;
		
	}

}
